package com.zy.business.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.zy.business.domain.*;
import com.zy.business.domain.vo.OverworkDto;
import com.zy.business.mapper.*;
import com.zy.business.service.OverworkService;
import com.zy.business.service.ShiftService;
import com.zy.common.constant.HttpStatus;
import com.zy.common.core.domain.entity.SysDept;
import com.zy.common.core.domain.entity.SysUser;
import com.zy.common.core.page.TableDataInfo;
import com.zy.common.utils.DateUtil;
import com.zy.common.utils.PageUtils;
import com.zy.common.utils.SecurityUtils;
import com.zy.common.utils.WebUtil;
import com.zy.system.mapper.SysDeptMapper;
import com.zy.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description: 加班管理 服务层实现
 * @author: whf
 * @create: 2022-08-01 10:25
 **/
@Service
public class OverworkServiceImpl extends ServiceImpl<OverworkMapper, TbOverwork> implements OverworkService {

    @Autowired
    private ISysUserService userService;

    @Resource
    private OverworkAuditMapper auditMapper;

    @Resource
    private SysDeptMapper deptMapper;

    @Resource
    private AttendanceMapper attendanceMapper;

    @Resource
    private HolidayMapper holidayMapper;

    @Resource
    private FaceLogMapper faceLogMapper;

    @Autowired
    private ShiftService shiftService;

    @Value("${OVERWORK_APPLY}")
    private String applyTemplateId;

    @Value("${OVERWORK_RESULT}")
    private String resultTemplateId;

    @Value("${APPID}")
    private String APPID;

    @Value("${APPSECRET}")
    private String APPSECRET;


    /**
     * @Description:新增加班
     * @author: zhangxiaojia
     * @date: 2020/3/26 下午 2:50
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOverwork(TbOverwork overwork) {
        overwork.setApplyId(SecurityUtils.getUserId());
        overwork.setCreateTime(new Date());
        overwork.setStatus(0);
        int row = baseMapper.insert(overwork);
        TbOverworkAudit tbOverworkAudit = new TbOverworkAudit();
        tbOverworkAudit.setOverworkId(overwork.getOverworkId());
        tbOverworkAudit.setStatus(0);
        tbOverworkAudit.setAuditUserId(overwork.getApproveId());
        tbOverworkAudit.setCreateBy(userService.selectUserById(overwork.getApproveId()).getUserName());
        tbOverworkAudit.setCreateTime(new Date());
        auditMapper.insert(tbOverworkAudit);
        this.sendMessage(tbOverworkAudit);
        return row;
    }


    /**
     * {{first.DATA}}
     * 申请人：{{keyword1.DATA}}
     * 申请部门：{{keyword2.DATA}}
     * 申请开始时间：{{keyword3.DATA}}
     * 申请结束时间：{{keyword4.DATA}}
     * 申请事由：{{keyword5.DATA}}
     * {{remark.DATA}}
     * @param audit
     * @return
     */
    private void sendMessage(TbOverworkAudit audit){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TbOverwork overwork = baseMapper.selectById(audit.getOverworkId());
        SysUser applyUser = userService.selectUserByUserName(overwork.getCreateBy());
        SysDept dept = deptMapper.selectDeptById(applyUser.getDeptId());
        SysUser auditUser = userService.selectUserById(audit.getAuditUserId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", auditUser.getOpenId());   // openid
        jsonObject.put("template_id", applyTemplateId);
        jsonObject.put("url", "http://kq.heshenghua.net/office/#/spDetail?type=audit&openId="+auditUser.getOpenId()+"&overworkId="+audit.getOverworkId());

        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", "您有一个新的加班申请待审核！");
        first.put("color", "#173177");
        //申请人
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", applyUser.getUserName());
        keyword1.put("color", "#173177");
        //申请部门
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", dept.getDeptName());
        keyword2.put("color", "#173177");
        //申请开始时间
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", sdf.format(overwork.getStartTime()));
        keyword3.put("color", "#173177");
        //申请结束时间
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", sdf.format(overwork.getEndTime()));
        keyword4.put("color", "#173177");
        //申请事由
        JSONObject keyword5 = new JSONObject();
        keyword5.put("value", overwork.getReason());
        keyword5.put("color", "#173177");

        JSONObject remark = new JSONObject();
        remark.put("value", "请尽快审核");
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("keyword4",keyword4);
        data.put("keyword5",keyword5);
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
    }

    /**
     * {{first.DATA}}
     * 申请部门：{{keyword1.DATA}}
     * 申请开始时间：{{keyword2.DATA}}
     * 申请结束时间：{{keyword3.DATA}}
     * 申请事由：{{keyword4.DATA}}
     * {{remark.DATA}}
     * @param audit
     * @return
     */
    public void sendResultMessage(TbOverworkAudit audit){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TbOverwork overwork = baseMapper.selectById(audit.getOverworkId());
        SysUser applyUser = userService.selectUserByUserName(overwork.getCreateBy());
        SysDept dept = deptMapper.selectDeptById(applyUser.getDeptId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        String firstStr = "";
        String remarkStr = "";
        String color = "#173177";
        if (audit.getStatus()==2){
            firstStr = "您的加班申请已通过";
            remarkStr = "通过";
        }else {
            firstStr = "您的加班申请未通过";
            remarkStr = "不通过";
            color = "#ff0000";
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", applyUser.getOpenId());   // openid
        jsonObject.put("template_id", resultTemplateId);
        jsonObject.put("url", "http://kq.heshenghua.net/office/#/spDetail?type=show&openId="+applyUser.getOpenId()+"&overworkId="+audit.getOverworkId());

        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", firstStr);
        first.put("color", "#173177");
        //申请部门
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", dept.getDeptName());
        keyword1.put("color", "#173177");
        //申请开始时间
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", sdf.format(overwork.getStartTime()));
        keyword2.put("color", "#173177");
        //申请结束时间
        JSONObject keyword3= new JSONObject();
        keyword3.put("value", sdf.format(overwork.getEndTime()));
        keyword3.put("color", "#173177");
        //申请事由
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", overwork.getReason());
        keyword4.put("color", "#173177");

        JSONObject remark = new JSONObject();
        remark.put("value", remarkStr);
        remark.put("color", color);

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("keyword4",keyword4);
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
    }

    /**
     * @Description:修改加班
     * @author: zhangxiaojia
     * @date: 2020/3/26 下午 2:50
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int editOverwork(TbOverwork overwork) {
        TbOverwork oldOverwork = baseMapper.selectById(overwork.getOverworkId());
        if (oldOverwork.getApproveId()!=overwork.getApproveId()) {
            TbOverworkAudit audit = auditMapper.selectOne(new QueryWrapper<TbOverworkAudit>().eq("OVERWORK_ID", overwork.getOverworkId()).eq("status",0));
            audit.setAuditUserId(overwork.getApproveId());
            audit.setUpdateBy(SecurityUtils.getUsername());
            audit.setUpdateTime(new Date());
            auditMapper.updateById(audit);
            this.sendMessage(audit);
        }
        overwork.setUpdateBy(SecurityUtils.getUsername());
        overwork.setUpdateTime(new Date());
        int row = baseMapper.updateById(overwork);
        return row;
    }

    /**
     * @Description:加班审核
     * @author: zhangxiaojia
     * @date: 2020/4/7 下午 5:43
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int audit(TbOverworkAudit audit){
        TbOverwork overwork = baseMapper.selectById(audit.getOverworkId());
        if (audit.getStatus()==1){
            overwork.setStatus(1);
            this.sendResultMessage(audit);
        }else if (audit.getStatus()==2){
            if (audit.getNextUserId()!=null){
                TbOverworkAudit tbOverworkAudit = new TbOverworkAudit();
                tbOverworkAudit.setOverworkId(overwork.getOverworkId());
                tbOverworkAudit.setStatus(0);
                tbOverworkAudit.setAuditUserId(audit.getNextUserId());
                tbOverworkAudit.setCreateBy(userService.selectUserById(audit.getNextUserId()).getUserName());
                tbOverworkAudit.setCreateTime(new Date());
                auditMapper.insert(tbOverworkAudit);
                this.sendMessage(tbOverworkAudit);
            }else {
                overwork.setStatus(2);
                SysUser applyUser = userService.selectUserByUserName(overwork.getCreateBy());
                applyUser.setOverworkHour(applyUser.getOverworkHour()+overwork.getWorkHour());
                applyUser.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
                applyUser.setUpdateTime(new Date());
                userService.updateUserProfile(applyUser);
                this.sendResultMessage(audit);
            }
        }
        audit.setUpdateBy(SecurityUtils.getUsername());
        audit.setUpdateTime(new Date());
        int row = auditMapper.updateById(audit);
        overwork.setUpdateBy(SecurityUtils.getUsername());
        overwork.setUpdateTime(new Date());
        this.updateById(overwork);
        return row;
    }

    @Override
    public TableDataInfo getTjData(){
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd");
        SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY");
        PageUtils.startPage();
        SysUser sysUser = new SysUser();
        sysUser.setIsBoss(0);
        List<SysUser> users = userService.selectUserList(sysUser);
        List<Map<String, Object>> dataList = new ArrayList<>();
        if (users!=null && users.size()>0){
            String now = sdf.format(new Date());
            String weekStart = sdf.format(DateUtil.getFirstDayOfWeek());
            String monthStart = DateUtil.monthFist();
            String quarterStart = DateUtil.getCurrentQuarterStart();
            for (SysUser user : users) {
                Map<String, Object> map = new HashMap<>();
                Map<String, Object> map1 = this.getMap(new QueryWrapper<TbOverwork>().select("IFNULL(sum(WORK_HOUR),0) as totalHour").eq("CREATE_BY", user.getUserName()).eq("STATUS", 2).apply("DATE(start_time)='" + sdf.format(new Date()) + "'"));
                Map<String, Object> map2 = this.getMap(new QueryWrapper<TbOverwork>().select("IFNULL(sum(WORK_HOUR),0) as totalHour").eq("CREATE_BY", user.getUserName()).eq("STATUS", 2).apply("DATE(start_time) between '"+weekStart+"' and '"+now+"'"));
                Map<String, Object> map3 = this.getMap(new QueryWrapper<TbOverwork>().select("IFNULL(sum(WORK_HOUR),0) as totalHour").eq("CREATE_BY", user.getUserName()).eq("STATUS", 2).apply("DATE(start_time) between '"+monthStart+"' and '"+now+"'"));
                Map<String, Object> map4 = this.getMap(new QueryWrapper<TbOverwork>().select("IFNULL(sum(WORK_HOUR),0) as totalHour").eq("CREATE_BY", user.getUserName()).eq("STATUS", 2).apply("DATE(start_time) between '"+quarterStart+"' and '"+now+"'"));
                Map<String, Object> map5 = this.getMap(new QueryWrapper<TbOverwork>().select("IFNULL(sum(WORK_HOUR),0) as totalHour").eq("CREATE_BY", user.getUserName()).eq("STATUS", 2).apply("YEAR(start_time)='" + sdf1.format(new Date()) + "'"));
                map.put("userName",user.getUserName());
                map.put("sabbaticalNum",user.getOverworkHour());
                map.put("todayNum",map1.get("totalHour"));
                map.put("weekNum",map2.get("totalHour"));
                map.put("monthNum",map3.get("totalHour"));
                map.put("quarterNum",map4.get("totalHour"));
                map.put("yearNum",map5.get("totalHour"));
                dataList.add(map);
            }
        }
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(dataList);
        rspData.setTotal(new PageInfo(users).getTotal());
        return rspData;
    }

    @Override
    public List<TbOverwork> list(OverworkDto overworkDto) {
        Long userId = SecurityUtils.getUserId();
        overworkDto.setUserId(userId);
        if ("approve".equals(overworkDto.getType())){
            return auditMapper.selectAuditList(overworkDto);
        }
        return baseMapper.list(overworkDto);
    }

    @Override
    public TbOverwork getDetail(Long overworkId) {
        return baseMapper.getDetail(overworkId);
    }

    @Override
    public Map<String, Object> getAuditList(Long overworkId) {
        Map<String, Object> map = new HashMap<>();
        //String punchStartTime = "";
        //String punchEndTime = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm");
        TbShift shift = shiftService.selectTbShiftById();
        TbOverwork overwork = baseMapper.selectById(overworkId);
        SysUser user = userService.selectUserById(overwork.getApplyId());
        List<TbOverworkAudit> auditList = auditMapper.selectList(new QueryWrapper<TbOverworkAudit>().eq("overwork_id",overworkId).orderByAsc("create_time"));
        map.put("auditList",auditList);

        String startTime = "";
        String endTime = "";
        String startDate = sdf.format(overwork.getStartTime());
        String endDate = sdf.format(overwork.getEndTime());
        List<TbAttendanceRecord> attendanceRecordList = null;
        if (startDate.equals(endDate)){
            if (holidayMapper.getIsHoliday(startDate)==1){
                if (sdf2.format(overwork.getStartTime()).compareTo(shift.getEndTime1())>=0 && sdf2.format(overwork.getEndTime()).compareTo(shift.getStartTime2())<=0) {
                    startTime = startDate + " "+shift.getEndTime1();
                    endTime = startDate + " "+shift.getStartTime2();
                    attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),startDate,startTime,endTime);
                }else {
                    startTime = startDate + " "+shift.getEndTime2();
                    attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),startDate,startTime,null);
                }
            }
            if (holidayMapper.getIsHoliday(startDate)==2){
                attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),startDate,null,null);
            }
        }else {
            if (holidayMapper.getIsHoliday(startDate)==1 && holidayMapper.getIsHoliday(endDate)==1){
                startTime = startDate + " "+shift.getEndTime2();
                endTime = endDate + " 06:00:00";
                attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),null,startTime,endTime);
            }
            if (holidayMapper.getIsHoliday(startDate)==1 && holidayMapper.getIsHoliday(endDate)==2){
                startTime = startDate + " "+shift.getEndTime2();
                endTime = endDate + " 23:59:59";
                attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),null,startTime,endTime);
            }
            if (holidayMapper.getIsHoliday(startDate)==2 && holidayMapper.getIsHoliday(endDate)==2){
                startTime = startDate + " 00:00:00";
                endTime = endDate + " 23:59:59";
                attendanceRecordList = attendanceMapper.getListByTime(user.getDingUserId(),null,startTime,endTime);
            }
        }
        map.put("attendanceRecordList",attendanceRecordList);

        /*String startTime = "";
        String endTime = sdf1.format(overwork.getStartTime());
        String startTime1 = sdf1.format(overwork.getEndTime());
        String workDate = "";
        //加班上班打卡
        if (holidayMapper.getIsHoliday(sdf.format(overwork.getStartTime()))==1) {
            startTime = sdf.format(overwork.getStartTime()) + " "+shift.getEndTime2();
        }
        workDate = sdf.format(overwork.getStartTime());
        List<TbAttendanceRecord> attendanceRecordList1 = attendanceMapper.getListByTime(user.getDingUserId(),workDate,startTime,endTime);
        if (attendanceRecordList1!=null && attendanceRecordList1.size()>0){
            punchStartTime = sdf1.format(attendanceRecordList1.get(0).getUserCheckTime());
        }else{
            List<TbFaceLog> faceLogList = faceLogMapper.getListByUserId(user.getUserId(),workDate,startTime,endTime);
            if (faceLogList!=null && faceLogList.size()>0){
                punchStartTime = sdf1.format(faceLogList.get(0).getCreateTime());
            }
        }
        //加班下班打卡
        if(!sdf.format(overwork.getStartTime()).equals(sdf.format(overwork.getEndTime()))){
            endTime = sdf.format(overwork.getEndTime()) + " "+shift.getStartTime1();
            workDate = "";
        }else{
            endTime = "";
            workDate = sdf.format(overwork.getEndTime());
        }
        List<TbAttendanceRecord> attendanceRecordList2 = attendanceMapper.getListByTime(user.getDingUserId(),workDate,startTime1,endTime);
        if (attendanceRecordList2!=null && attendanceRecordList2.size()>0){
            punchEndTime = sdf1.format(attendanceRecordList2.get(0).getUserCheckTime());
        }else{
            List<TbFaceLog> faceLogList = faceLogMapper.getListByUserId(user.getUserId(),workDate,startTime1,null);
            if (faceLogList!=null && faceLogList.size()>0){
                punchEndTime = sdf1.format(faceLogList.get(0).getCreateTime());
            }
        }
        map.put("punchStartTime",punchStartTime);
        map.put("punchEndTime",punchEndTime);*/
        return map;
    }
}
